#pragma warning( disable : 4290 )
#ifndef __SmartString_h__
#define __SmartString_h__
#include "SmartArray.h"
#include "Iterable.h"
#include <iostream>

class SmartString:public SmartObject,public Iterable
{
private:
	char* mStr;
protected:
	void Allocate(unsigned int) throw(Iterable::UnneededAllocation);
public:
	SmartObject_Type_Information("SmartString")//Ugly, but it works.
	class SplitPoint
	{
	protected:
		SmartArray<SmartString> mKeys;
		Reference<SmartString> mPoints;
	public:
		SplitPoint();
		unsigned int operator()(char*) const;
		SplitPoint& AddPoint( const char* );
		SplitPoint& AddPoint( const char );
		~SplitPoint();
		class NoSplit
		{
			protected:
				unsigned int mLen;
			public:
				NoSplit(unsigned int aLen);
				operator unsigned int();
		};

		class Split:public NoSplit
		{
			private:
				SmartString* newString;
			public:
				Split(unsigned int aLen,char* ptr);
				SmartString* operator()();
				~Split();
		};
	};
	static unsigned int gBufferSize;
	SmartString& Append( const char* );
	SmartString& Append( const char*, unsigned int );
	SmartString& Append( const char );
	SmartString& Insert( const char*, int );
	SmartString& Insert( const char*, unsigned int, int);
	SmartString& Prepend( const char* );
	SmartString& Prepend( const char*, unsigned int );
	SmartString& Empty(void);
	const SmartArray<SmartString> Explode( const SplitPoint& );
	SmartString operator [] ( const Iterable::Slice& );
	int operator [] ( char );
	char operator [] ( int );
	const SmartArray<SmartString> operator [] ( const SmartString& );
	SmartString( const char* );
	SmartString( const char*, unsigned int );
	SmartString( const SmartString& );
	SmartString( void );
	~SmartString( void );
	operator const char* () const;
	bool operator == ( const char* ) const;
	int Similar( const char* );
	static int Similar( const char*, const char* );
	static unsigned int Contains( const char*, const char*, bool=true );
	unsigned int Contains( const char*,bool=true ) const;
	void ExportToFile( std::ostream& );
	void LoadFromFile( std::istream& );
};
#endif
